package com.meiyuetao.myt.sale.entity;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import lab.s2jh.auth.entity.Department;
import lab.s2jh.auth.entity.User;
import lab.s2jh.bpm.BpmTrackable;
import lab.s2jh.core.annotation.MetaData;
import lab.s2jh.core.entity.annotation.SkipParamBind;
import lab.s2jh.core.web.json.DateJsonSerializer;
import lab.s2jh.core.web.json.DateTimeJsonSerializer;
import lab.s2jh.core.web.json.EntityIdDisplaySerializer;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Formula;
import org.hibernate.envers.NotAudited;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.collect.Lists;
import com.meiyuetao.myt.core.constant.StorageModeEnum;
import com.meiyuetao.myt.core.constant.VoucherStateEnum;
import com.meiyuetao.myt.core.entity.MytBaseEntity;
import com.meiyuetao.myt.customer.entity.CustomerProfile;
import com.meiyuetao.myt.finance.entity.AccountSubject;
import com.meiyuetao.myt.partner.entity.Partner;
import com.meiyuetao.myt.purchase.entity.Supplier;

@MetaData("销售（发货）单")
@Entity
@Table(name = "myt_sale_delivery")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class SaleDelivery extends MytBaseEntity implements BpmTrackable {
    private static final long serialVersionUID = 1L;
    @MetaData("唯一凭证号")
    private String voucher;
    @MetaData("凭证日期")
    private Date voucherDate;
    @MetaData("凭证状态")
    private VoucherStateEnum voucherState = VoucherStateEnum.DRAFT;
    @MetaData("经办人")
    private User voucherUser;
    @MetaData("经办部门")
    private Department voucherDepartment;

    @MetaData(value = "参考来源", comments = "如填写京东，淘宝，天猫、美月淘、哎呦盒子等标识采购来源的信息")
    private String referenceSource;
    @MetaData(value = "参考凭证号", comments = "如京东，淘宝，天猫、美月淘、哎呦盒子等订单号等")
    private String referenceVoucher;

    @MetaData(value = "标题摘要")
    private String title;

    @MetaData("收取客户的运费")
    private BigDecimal chargeLogisticsAmount = BigDecimal.ZERO;
    @MetaData("备注信息")
    private String memo;

    @MetaData(value = "关联销售订单行项", comments = "限制一个销售单只能最多关联一个销售订单行项")
    private BoxOrderDetail boxOrderDetail;

    private List<SaleDeliveryDetail> saleDeliveryDetails = new ArrayList<SaleDeliveryDetail>();
    @MetaData("快照记录发货地址信息")
    private String deliveryAddr;
    @MetaData("收货人电话")
    private String mobilePhone;
    @MetaData("收货人")
    private String receivePerson;
    @MetaData("邮编")
    private String postCode;
    @MetaData("收货省")
    private String deliveryProvince;
    @MetaData("收货城市")
    private String deliveryCity;
    @MetaData("收货街道")
    private String deliveryStreet;

    @MetaData(value = "折后商品总金额", comments = "冗余汇总商品销售金额，便于利润率统计")
    private BigDecimal commodityAmount = BigDecimal.ZERO;
    @MetaData(value = "商品总成本", comments = "冗余汇总商品总成本，便于利润率统计")
    private BigDecimal commodityCostAmount = BigDecimal.ZERO;
    @MetaData(value = "整单总金额", comments = "剩余")
    private BigDecimal totalAmount = BigDecimal.ZERO;
    @MetaData(value = "已付款金额", comments = "剩余款项按照应收账款记账")
    private BigDecimal payedAmount = BigDecimal.ZERO;

    @MetaData(value = "整单总税", comments = "冗余汇总商品应交税费")
    private BigDecimal totalTaxAmount = BigDecimal.ZERO;
    @MetaData(value = "整单总税", comments = "冗余汇总：commodityAmount+totalTaxAmount")
    private BigDecimal commodityAndTaxAmount = BigDecimal.ZERO;
    @MetaData("总计原始金额")
    private BigDecimal totalOriginalAmount = BigDecimal.ZERO;
    @MetaData("*整单折扣率(%)")
    private BigDecimal discountRate;
    @MetaData("整单折扣金额")
    private BigDecimal discountAmount = BigDecimal.ZERO;
    @MetaData("整单总成本")
    private BigDecimal totalCostAmount = BigDecimal.ZERO;

    @MetaData(value = "收款会计科目")
    private AccountSubject accountSubject;
    @MetaData(value = "付款参考信息", comments = "一般用于记录其他三方系统付款的凭证信息")
    private String paymentReference;

    @MetaData("提交时间")
    private Date submitDate;
    @MetaData("审核时间")
    private Date auditDate;
    @MetaData("审核人")
    private String auditBy;
    @MetaData("红冲时间")
    private Date redwordDate;
    @MetaData(value = "最近操作摘要")
    private String lastOperationSummary;

    @MetaData("销售客户")
    private CustomerProfile customerProfile;
    @MetaData("拣货人")
    private User pickUser;
    @MetaData("拣货时间")
    private Date pickTime;
    @MetaData("发货人")
    private User deliveryUser;
    @MetaData("发货时间")
    private Date deliveryTime;
    @MetaData("快递公司")
    private Supplier logistics;
    @MetaData("快递单号")
    private String logisticsNo;
    @MetaData("运费")
    private BigDecimal logisticsAmount = BigDecimal.ZERO;

    @MetaData("快递发货数据模板")
    private ExpressDataTemplate expressDataTemplate;
    @MetaData("销售发货类型")
    private DeliveryTypeEnum deliveryType = DeliveryTypeEnum.READY;

    @MetaData(value = "毛利率")
    private BigDecimal profitRate;

    @MetaData(value = "毛利额")
    private BigDecimal profitAmount;

    @MetaData(value = "流程当前任务节点")
    private String activeTaskName;

    @MetaData("分销代理商")
    private Partner agentPartner;
    @MetaData("指派时间")
    private Date agentAssignDate;
    @MetaData("接单时间")
    private Date agentAcceptDate;

    @MetaData("已消息邮件通知的分销代理商")
    private Partner agentPartnerNotified;

    @MetaData("代发货库房")
    private Partner stockPartner;

    // 出库单相关信息
    @MetaData("发货方式")
    private String deliveryMode;

    @MetaData("提货人")
    private String pickUpPerson;
    @MetaData("提货人单位")
    private String pickUpCompany;
    @MetaData("提货人电话")
    private String pickUpMobile;
    @MetaData("提货日期")
    private Date pickUpDate;
    @MetaData("出库审核人")
    private String pickUpAuditBy;
    @MetaData("提货地址")
    private String pickUpDeliveryAddr;
    private SaleReturn saleReturn;
    private Date reserveDeliveryTime;

    private List<SaleDeliveryPic> saleDeliveryPics = Lists.newArrayList();

    public enum DeliveryTypeEnum {
        @MetaData("代发")
        AGENT, @MetaData("直邮")
        DIRECT, @MetaData("普邮")
        INNER_EXPRESS, @MetaData("直邮特快")
        EXPRESS, @MetaData("直邮普邮")
        POST, @MetaData("直邮DHL")
        DHL, @MetaData("直邮TNT")
        TNT, @MetaData("现货")
        READY;

    }

    @MetaData(value = "库存模式", comments = "用在采购、销售流程，控制入库出库方式")
    private StorageModeEnum storageMode = StorageModeEnum.MU;
    @MetaData("发货单状态")
    private DeliveryProcessTypeEnum processType = DeliveryProcessTypeEnum.EDIT;

    public enum DeliveryProcessTypeEnum {
        @MetaData("编辑")
        EDIT, @MetaData("提交")
        POST, @MetaData("审核通过")
        PASS, @MetaData("驳回")
        REJECT, @MetaData("已拣货")
        PICK, @MetaData("已接单")
        ACCEPT, @MetaData("已发货")
        DELIVERY, @MetaData("已红冲")
        REDW;

    }

    @Column(length = 32)
    @JsonProperty
    public String getLogisticsNo() {
        return logisticsNo;
    }

    public void setLogisticsNo(String logisticsNo) {
        this.logisticsNo = logisticsNo;
    }

    @JsonProperty
    public BigDecimal getLogisticsAmount() {
        return logisticsAmount;
    }

    public void setLogisticsAmount(BigDecimal logisticsAmount) {
        this.logisticsAmount = logisticsAmount;
    }

    @Column(length = 128, nullable = false, unique = true, updatable = false)
    @JsonProperty
    public String getVoucher() {
        return voucher;
    }

    public void setVoucher(String voucher) {
        this.voucher = voucher;
    }

    @Column(length = 1000)
    @JsonProperty
    public String getDeliveryAddr() {
        return deliveryAddr;
    }

    public void setDeliveryAddr(String deliveryAddr) {
        this.deliveryAddr = deliveryAddr;
    }

    @Column(length = 32)
    @JsonProperty
    public String getMobilePhone() {
        return mobilePhone;
    }

    public void setMobilePhone(String mobilePhone) {
        this.mobilePhone = mobilePhone;
    }

    @Column(length = 16)
    @JsonProperty
    public String getReceivePerson() {
        return receivePerson;
    }

    public void setReceivePerson(String receivePerson) {
        this.receivePerson = receivePerson;
    }

    @Column(length = 16)
    public String getPostCode() {
        return postCode;
    }

    public void setPostCode(String postCode) {
        this.postCode = postCode;
    }

    @Column(length = 64)
    public String getDeliveryProvince() {
        return deliveryProvince;
    }

    public void setDeliveryProvince(String deliveryProvince) {
        this.deliveryProvince = deliveryProvince;
    }

    @Column(length = 64)
    public String getDeliveryCity() {
        return deliveryCity;
    }

    public void setDeliveryCity(String deliveryCity) {
        this.deliveryCity = deliveryCity;
    }

    @Column(length = 256)
    public String getDeliveryStreet() {
        return deliveryStreet;
    }

    public void setDeliveryStreet(String deliveryStreet) {
        this.deliveryStreet = deliveryStreet;
    }

    @OneToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "supplier_sid", nullable = true)
    @JsonProperty
    public Supplier getLogistics() {
        return logistics;
    }

    public void setLogistics(Supplier logistics) {
        this.logistics = logistics;
    }

    public String getMemo() {
        return memo;
    }

    public void setMemo(String memo) {
        this.memo = memo;
    }

    @OneToMany(mappedBy = "saleDelivery", cascade = CascadeType.ALL, orphanRemoval = true)
    public List<SaleDeliveryDetail> getSaleDeliveryDetails() {
        return saleDeliveryDetails;
    }

    public void setSaleDeliveryDetails(List<SaleDeliveryDetail> saleDeliveryDetails) {
        this.saleDeliveryDetails = saleDeliveryDetails;
    }

    @Column(precision = 18, scale = 2, nullable = false)
    @JsonProperty
    public BigDecimal getTotalAmount() {
        return totalAmount;
    }

    public void setTotalAmount(BigDecimal totalAmount) {
        this.totalAmount = totalAmount;
    }

    @Column(nullable = false)
    @JsonProperty
    @JsonSerialize(using = DateJsonSerializer.class)
    @Temporal(TemporalType.DATE)
    public Date getVoucherDate() {
        return voucherDate;
    }

    public void setVoucherDate(Date voucherDate) {
        this.voucherDate = voucherDate;
    }

    @JsonProperty
    public BigDecimal getCommodityAmount() {
        return commodityAmount;
    }

    public void setCommodityAmount(BigDecimal commodityAmount) {
        this.commodityAmount = commodityAmount;
    }

    public BigDecimal getDiscountRate() {
        return discountRate;
    }

    public void setDiscountRate(BigDecimal discountRate) {
        this.discountRate = discountRate;
    }

    public BigDecimal getDiscountAmount() {
        return discountAmount;
    }

    public void setDiscountAmount(BigDecimal discountAmount) {
        this.discountAmount = discountAmount;
    }

    @Column(precision = 18, scale = 2, nullable = true)
    public BigDecimal getTotalTaxAmount() {
        return totalTaxAmount;
    }

    public void setTotalTaxAmount(BigDecimal totalTaxAmount) {
        this.totalTaxAmount = totalTaxAmount;
    }

    @Column(precision = 18, scale = 2, nullable = true)
    @JsonProperty
    public BigDecimal getTotalCostAmount() {
        return totalCostAmount;
    }

    public void setTotalCostAmount(BigDecimal totalCostAmount) {
        this.totalCostAmount = totalCostAmount;
    }

    @Column(precision = 18, scale = 2, nullable = true)
    public BigDecimal getCommodityCostAmount() {
        return commodityCostAmount;
    }

    public void setCommodityCostAmount(BigDecimal commodityCostAmount) {
        this.commodityCostAmount = commodityCostAmount;
    }

    @OneToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "customer_profile_sid", nullable = false)
    @JsonProperty
    public CustomerProfile getCustomerProfile() {
        return customerProfile;
    }

    public void setCustomerProfile(CustomerProfile customerProfile) {
        this.customerProfile = customerProfile;
    }

    @Enumerated(EnumType.STRING)
    @Column(length = 8, nullable = true)
    @JsonProperty
    public VoucherStateEnum getVoucherState() {
        return voucherState;
    }

    @SkipParamBind
    public void setVoucherState(VoucherStateEnum voucherState) {
        this.voucherState = voucherState;
    }

    @Column(precision = 18, scale = 2, nullable = false)
    public BigDecimal getCommodityAndTaxAmount() {
        return commodityAndTaxAmount;
    }

    public void setCommodityAndTaxAmount(BigDecimal commodityAndTaxAmount) {
        this.commodityAndTaxAmount = commodityAndTaxAmount;
    }

    @Column(precision = 18, scale = 2)
    @JsonProperty
    public BigDecimal getChargeLogisticsAmount() {
        return chargeLogisticsAmount;
    }

    public void setChargeLogisticsAmount(BigDecimal chargeLogisticsAmount) {
        this.chargeLogisticsAmount = chargeLogisticsAmount;
    }

    @JsonProperty
    public BigDecimal getPayedAmount() {
        return payedAmount;
    }

    public void setPayedAmount(BigDecimal payedAmount) {
        this.payedAmount = payedAmount;
    }

    @ManyToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "voucher_user_id", nullable = false)
    @JsonProperty
    @JsonSerialize(using = EntityIdDisplaySerializer.class)
    public User getVoucherUser() {
        return voucherUser;
    }

    public void setVoucherUser(User voucherUser) {
        this.voucherUser = voucherUser;
    }

    @ManyToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "voucher_department_id", nullable = false)
    @JsonProperty
    public Department getVoucherDepartment() {
        return voucherDepartment;
    }

    public void setVoucherDepartment(Department voucherDepartment) {
        this.voucherDepartment = voucherDepartment;
    }

    @Column(length = 100, nullable = false)
    @JsonProperty
    public String getReferenceSource() {
        return referenceSource;
    }

    public void setReferenceSource(String referenceSource) {
        this.referenceSource = referenceSource;
    }

    @JsonProperty
    @Column(length = 100, nullable = false)
    public String getReferenceVoucher() {
        return referenceVoucher;
    }

    public void setReferenceVoucher(String referenceVoucher) {
        this.referenceVoucher = referenceVoucher;
    }

    @Column(length = 2000)
    @JsonProperty
    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    @JsonProperty
    @JsonSerialize(using = DateTimeJsonSerializer.class)
    public Date getPickTime() {
        return pickTime;
    }

    public void setPickTime(Date pickTime) {
        this.pickTime = pickTime;
    }

    @JsonProperty
    public BigDecimal getTotalOriginalAmount() {
        return totalOriginalAmount;
    }

    public void setTotalOriginalAmount(BigDecimal totalOriginalAmount) {
        this.totalOriginalAmount = totalOriginalAmount;
    }

    @ManyToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "delivery_user_id", nullable = true)
    @JsonProperty
    public User getDeliveryUser() {
        return deliveryUser;
    }

    public void setDeliveryUser(User deliveryUser) {
        this.deliveryUser = deliveryUser;
    }

    @JsonProperty
    @JsonSerialize(using = DateTimeJsonSerializer.class)
    public Date getDeliveryTime() {
        return deliveryTime;
    }

    public void setDeliveryTime(Date deliveryTime) {
        this.deliveryTime = deliveryTime;
    }

    @Lob
    @JsonIgnore
    public String getPaymentReference() {
        return paymentReference;
    }

    public void setPaymentReference(String paymentReference) {
        this.paymentReference = paymentReference;
    }

    @OneToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "template_sid", nullable = true)
    @JsonProperty
    public ExpressDataTemplate getExpressDataTemplate() {
        return expressDataTemplate;
    }

    public void setExpressDataTemplate(ExpressDataTemplate expressDataTemplate) {
        this.expressDataTemplate = expressDataTemplate;
    }

    @ManyToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "account_subject_id")
    public AccountSubject getAccountSubject() {
        return accountSubject;
    }

    public void setAccountSubject(AccountSubject accountSubject) {
        this.accountSubject = accountSubject;
    }

    @Enumerated(EnumType.STRING)
    @Column(length = 16)
    @JsonProperty
    public DeliveryTypeEnum getDeliveryType() {
        return deliveryType;
    }

    public void setDeliveryType(DeliveryTypeEnum deliveryType) {
        this.deliveryType = deliveryType;
    }

    @Formula("(case when total_amount=0 then -1 else (total_amount - total_cost_amount)/total_amount end)")
    @JsonProperty
    @NotAudited
    public BigDecimal getProfitRate() {
        return profitRate;
    }

    public void setProfitRate(BigDecimal profitRate) {
        this.profitRate = profitRate;
    }

    @Formula("(total_amount - total_cost_amount)")
    @JsonProperty
    @NotAudited
    public BigDecimal getProfitAmount() {
        return profitAmount;
    }

    public void setProfitAmount(BigDecimal profitAmount) {
        this.profitAmount = profitAmount;
    }

    @JsonProperty
    public String getLastOperationSummary() {
        return lastOperationSummary;
    }

    public void setLastOperationSummary(String lastOperationSummary) {
        this.lastOperationSummary = lastOperationSummary;
    }

    @JsonProperty
    public Date getSubmitDate() {
        return submitDate;
    }

    @SkipParamBind
    public void setSubmitDate(Date submitDate) {
        this.submitDate = submitDate;
    }

    @JsonProperty
    public String getActiveTaskName() {
        return activeTaskName;
    }

    public void setActiveTaskName(String activeTaskName) {
        this.activeTaskName = activeTaskName;
    }

    @Override
    @Transient
    @JsonIgnore
    public String getBpmBusinessKey() {
        return voucher;
    }

    @JsonProperty
    public Date getAuditDate() {
        return auditDate;
    }

    @SkipParamBind
    public void setAuditDate(Date auditDate) {
        this.auditDate = auditDate;
    }

    public Date getRedwordDate() {
        return redwordDate;
    }

    @SkipParamBind
    public void setRedwordDate(Date redwordDate) {
        this.redwordDate = redwordDate;
    }

    @ManyToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "ORDER_DETAIL_SID", nullable = true)
    @JsonIgnore
    public BoxOrderDetail getBoxOrderDetail() {
        return boxOrderDetail;
    }

    public void setBoxOrderDetail(BoxOrderDetail boxOrderDetail) {
        this.boxOrderDetail = boxOrderDetail;
    }

    @OneToOne
    @JoinColumn(name = "pick_user_id")
    public User getPickUser() {
        return pickUser;
    }

    public void setPickUser(User pickUser) {
        this.pickUser = pickUser;
    }

    @JsonProperty
    public String getAuditBy() {
        return auditBy;
    }

    public void setAuditBy(String auditBy) {
        this.auditBy = auditBy;
    }

    @OneToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "agent_partner_sid")
    @JsonProperty
    public Partner getAgentPartner() {
        return agentPartner;
    }

    public void setAgentPartner(Partner agentPartner) {
        this.agentPartner = agentPartner;
    }

    @OneToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "stock_partner_sid")
    @JsonProperty
    public Partner getStockPartner() {
        return stockPartner;
    }

    public void setStockPartner(Partner stockPartner) {
        this.stockPartner = stockPartner;
    }

    @JsonProperty
    public String getDeliveryMode() {
        return deliveryMode;
    }

    public void setDeliveryMode(String deliveryMode) {
        this.deliveryMode = deliveryMode;
    }

    @JsonProperty
    public String getPickUpPerson() {
        return pickUpPerson;
    }

    public void setPickUpPerson(String pickUpPerson) {
        this.pickUpPerson = pickUpPerson;
    }

    @JsonProperty
    public String getPickUpCompany() {
        return pickUpCompany;
    }

    public void setPickUpCompany(String pickUpCompany) {
        this.pickUpCompany = pickUpCompany;
    }

    @JsonProperty
    public String getPickUpMobile() {
        return pickUpMobile;
    }

    public void setPickUpMobile(String pickUpMobile) {
        this.pickUpMobile = pickUpMobile;
    }

    @JsonProperty
    public String getPickUpAuditBy() {
        return pickUpAuditBy;
    }

    public void setPickUpAuditBy(String pickUpAuditBy) {
        this.pickUpAuditBy = pickUpAuditBy;
    }

    @JsonSerialize(using = DateJsonSerializer.class)
    @JsonProperty
    public Date getPickUpDate() {
        return pickUpDate;
    }

    public void setPickUpDate(Date pickUpDate) {
        this.pickUpDate = pickUpDate;
    }

    @Column(length = 1000)
    @JsonProperty
    public String getPickUpDeliveryAddr() {
        return pickUpDeliveryAddr;
    }

    public void setPickUpDeliveryAddr(String pickUpDeliveryAddr) {
        this.pickUpDeliveryAddr = pickUpDeliveryAddr;
    }

    @JsonProperty
    public Date getAgentAssignDate() {
        return agentAssignDate;
    }

    public void setAgentAssignDate(Date agentAssignDate) {
        this.agentAssignDate = agentAssignDate;
    }

    @JsonProperty
    public Date getAgentAcceptDate() {
        return agentAcceptDate;
    }

    public void setAgentAcceptDate(Date agentAcceptDate) {
        this.agentAcceptDate = agentAcceptDate;
    }

    @JsonProperty
    @Transient
    public Long getAgentAssignDatePassDuration() {
        if (agentAssignDate == null) {
            return 0L;
        }
        return (new Date().getTime() - agentAssignDate.getTime()) / (1000 * 60 * 60);
    }

    @OneToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "agent_partner_notified_sid")
    public Partner getAgentPartnerNotified() {
        return agentPartnerNotified;
    }

    public void setAgentPartnerNotified(Partner agentPartnerNotified) {
        this.agentPartnerNotified = agentPartnerNotified;
    }

    @Enumerated(EnumType.STRING)
    @Column(length = 16)
    @JsonProperty
    public DeliveryProcessTypeEnum getProcessType() {
        return processType;
    }

    public void setProcessType(DeliveryProcessTypeEnum processType) {
        this.processType = processType;
    }

    @OneToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "sale_return_sid")
    public SaleReturn getSaleReturn() {
        return saleReturn;
    }

    public void setSaleReturn(SaleReturn saleReturn) {
        this.saleReturn = saleReturn;
    }

    @OneToMany(mappedBy = "saleDelivery", cascade = CascadeType.ALL, orphanRemoval = true)
    @NotAudited
    public List<SaleDeliveryPic> getSaleDeliveryPics() {
        return saleDeliveryPics;
    }

    public void setSaleDeliveryPics(List<SaleDeliveryPic> saleDeliveryPics) {
        this.saleDeliveryPics = saleDeliveryPics;
    }

    @JsonProperty
    @JsonSerialize(using = DateJsonSerializer.class)
    public Date getReserveDeliveryTime() {
        return reserveDeliveryTime;
    }

    public void setReserveDeliveryTime(Date reserveDeliveryTime) {
        this.reserveDeliveryTime = reserveDeliveryTime;
    }

    @Enumerated(EnumType.STRING)
    @Column(length = 8)
    @JsonProperty
    public StorageModeEnum getStorageMode() {
        return storageMode;
    }

    public void setStorageMode(StorageModeEnum storageMode) {
        this.storageMode = storageMode;
    }

    @Transient
    @Override
    public String getExtraInfo() {
        return null;
    }

}